package at.jaki.ubb.crawling.appThreads;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.apache.log4j.Logger;

import at.jaki.ubb.crawling.dataTransformer.DataTransformerManager;
import at.jaki.ubb.crawling.model.RawData;

/**
 * This singleton will run a separate thread. It will watch the Raw Data Set,
 * and send it's elements to the data transformers.
 * 
 * @author Attila Jakabfi
 * 
 */
public final class DataSet extends AbstractCrawlerThread {

	private static final Logger LOG = Logger.getLogger(DataSet.class);

	private static DataSet instance;

	public static synchronized DataSet getInstance() {
		if (instance == null) {
			instance = new DataSet();
		}
		return instance;
	}

	/**
	 * Priority queue that hold all the targets.
	 */
	private Set<RawData<?>> set = new HashSet<RawData<?>>();

	/**
	 * private constructor for singleton.
	 */
	private DataSet() {
		LOG.info("Creating Data Set");
	}

	private Set<RawData<?>> getSet() {
		return set;
	}

	/**
	 * Sends one element from the dataset to the data transformers.
	 */
	@Override
	protected void doWork() {
		RawData<?> rd = null;
		synchronized (DataSet.class) {
			Iterator<RawData<?>> iterator = getSet().iterator();
			if (iterator.hasNext()) {
				rd = iterator.next();
				iterator.remove();
				LOG.debug("Found raw data: '" + rd + "'");
			}
		}
		if (rd != null) {
			DataTransformerManager.getInstance().call(rd);
		}
	}

	/**
	 * Will clear the data set.
	 */
	@Override
	protected void clear() {
		synchronized (DataSet.class) {
			getSet().clear();
		}
	}

	/**
	 * Will add an element to the Data Set
	 * 
	 * @param rd {@link RawData}
	 */
	public void add(RawData<?> rd) {
		LOG.debug("add: " + rd);
		synchronized (DataSet.class) {
			getSet().add(rd);
		}
	}

	/**
	 * @return the number of elements waiting in the data set
	 */
	public int getSize() {
		return set.size();
	}

}
